package com.kexio.pay.service.impl;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;

import com.kexio.common.dto.Result;
import com.kexio.pay.config.PaymentProperties;
import com.kexio.pay.dto.PaymentRequest;
import com.kexio.pay.dto.PaymentResponse;
import com.kexio.pay.entity.PaymentCallback;
import com.kexio.pay.entity.PaymentOrder;
import com.kexio.pay.enums.PaymentMethod;
import com.kexio.pay.enums.PaymentStatus;
import com.kexio.pay.event.PaymentSuccessEvent;
import com.kexio.pay.provider.PaymentProvider;
import com.kexio.pay.service.PaymentService;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;

/**
 * 支付服务实现
 * 
 * @author Kexio Team
 * @since 1.0.0
 */
@Service
@ConditionalOnProperty(prefix = "kexio.pay", name = "enabled", havingValue = "true")
public class PaymentServiceImpl implements PaymentService {
    
    private static final Logger logger = LoggerFactory.getLogger(PaymentServiceImpl.class);
    
    @Autowired
    private PaymentProperties paymentProperties;
    
    @Autowired(required = false)
    private List<PaymentProvider> paymentProviders;
    
    @Autowired
    private ApplicationEventPublisher eventPublisher;
    
    // 模拟存储 (实际应该注入Mapper)
    private final Map<String, PaymentOrder> orderStorage = new HashMap<>();
    
    @Override
    public Result<PaymentResponse> createPayment(PaymentRequest request) {
        logger.info("创建支付订单: orderNo={}, method={}, amount={}", 
                   request.getOrderNo(), request.getPaymentMethod(), request.getAmount());
        
        try {
            // 参数验证
            Result<String> validateResult = validatePaymentRequest(request);
            if (!validateResult.isSuccess()) {
                return Result.error(validateResult.getMessage());
            }
            
            // 获取支付提供商
            PaymentProvider provider = getPaymentProvider(request.getPaymentMethod());
            if (provider == null) {
                return Result.error("不支持的支付方式: " + request.getPaymentMethod());
            }
            
            // 创建本地订单
            PaymentOrder order = createLocalOrder(request);
            orderStorage.put(order.getOrderNo(), order);
            
            // 调用第三方创建支付
            PaymentResponse response = provider.createPayment(request);
            
            // 更新订单状态
            if (response.isSuccess()) {
                order.setThirdPartyOrderNo(response.getThirdPartyOrderNo());
                order.setStatus(PaymentStatus.PROCESSING.getCode());
                logger.info("支付订单创建成功: orderNo={}, thirdPartyOrderNo={}", 
                           order.getOrderNo(), response.getThirdPartyOrderNo());
            } else {
                order.setStatus(PaymentStatus.FAILED.getCode());
                order.setErrorCode(response.getErrorCode());
                order.setErrorMessage(response.getMessage());
                logger.warn("支付订单创建失败: orderNo={}, error={}", 
                           order.getOrderNo(), response.getMessage());
            }
            
            return Result.success(response.getMessage(), response);
            
        } catch (Exception e) {
            logger.error("创建支付订单异常", e);
            return Result.error("创建支付订单异常: " + e.getMessage());
        }
    }
    
    @Override
    public PaymentStatus queryPaymentStatus(String orderNo) {
        PaymentOrder order = orderStorage.get(orderNo);
        if (order == null) {
            return PaymentStatus.FAILED;
        }
        
        try {
            // 获取支付提供商
            PaymentProvider provider = getPaymentProvider(order.getPaymentMethod());
            if (provider == null) {
                return PaymentStatus.fromCode(order.getStatus());
            }
            
            // 查询第三方状态
            PaymentStatus status = provider.queryPayment(orderNo, order.getThirdPartyOrderNo());
            
            // 更新本地状态
            if (!order.getStatus().equals(status.getCode())) {
                order.setStatus(status.getCode());
                if (status.isSuccess()) {
                    order.setSuccessTime(LocalDateTime.now());
                }
            }
            
            return status;
            
        } catch (Exception e) {
            logger.error("查询支付状态异常: orderNo={}", orderNo, e);
            return PaymentStatus.fromCode(order.getStatus());
        }
    }
    
    @Override
    public PaymentOrder queryPaymentOrder(String orderNo) {
        return orderStorage.get(orderNo);
    }
    
    @Override
    public Result<Boolean> closePayment(String orderNo) {
        PaymentOrder order = orderStorage.get(orderNo);
        if (order == null) {
            return Result.error("订单不存在");
        }
        
        try {
            // 获取支付提供商
            PaymentProvider provider = getPaymentProvider(order.getPaymentMethod());
            if (provider == null) {
                return Result.error("支付提供商不可用");
            }
            
            // 关闭第三方订单
            boolean result = provider.closePayment(order.getOrderNo(), order.getThirdPartyOrderNo());
            
            if (result) {
                order.setStatus(PaymentStatus.CLOSED.getCode());
                order.setCloseTime(LocalDateTime.now());
                logger.info("支付订单关闭成功: orderNo={}", orderNo);
            } else {
                logger.warn("支付订单关闭失败: orderNo={}", orderNo);
            }
            
            return Result.success(result ? "订单关闭成功" : "订单关闭失败", result);
            
        } catch (Exception e) {
            logger.error("关闭支付订单异常: orderNo={}", orderNo, e);
            return Result.error("关闭支付订单异常: " + e.getMessage());
        }
    }
    
    @Override
    public Result<Boolean> cancelPayment(String orderNo, String reason) {
        PaymentOrder order = orderStorage.get(orderNo);
        if (order == null) {
            return Result.error("订单不存在");
        }
        
        if (!PaymentStatus.fromCode(order.getStatus()).canCancel()) {
            return Result.error("订单状态不允许取消");
        }
        
        order.setStatus(PaymentStatus.CANCELLED.getCode());
        order.setCloseTime(LocalDateTime.now());
        order.setErrorMessage(reason);
        
        logger.info("支付订单取消成功: orderNo={}, reason={}", orderNo, reason);
        return Result.success("订单取消成功", true);
    }
    
    @Override
    public Result<Boolean> handleCallback(String provider, PaymentCallback callback) {
        logger.info("处理支付回调: provider={}, orderNo={}, type={}", 
                   provider, callback.getOrderNo(), callback.getCallbackType());
        
        try {
            // 获取支付提供商
            PaymentProvider paymentProvider = getPaymentProviderById(provider);
            if (paymentProvider == null) {
                return Result.error("不支持的支付提供商: " + provider);
            }
            
            // 处理回调
            PaymentProvider.CallbackResult result = paymentProvider.processCallback(callback);
            
            if (result.isSuccess()) {
                // 更新订单状态
                PaymentOrder order = orderStorage.get(result.getOrderNo());
                if (order != null) {
                    order.setStatus(result.getStatus().getCode());
                    order.setThirdPartyTradeNo(result.getThirdPartyTradeNo());
                    if (result.getStatus().isSuccess()) {
                        order.setSuccessTime(LocalDateTime.now());
                        
                        // ✅ 发布支付成功事件，通知业务模块执行后续逻辑
                        PaymentSuccessEvent event = new PaymentSuccessEvent(
                            this,
                            order.getOrderNo(),
                            order.getBusinessType(),
                            order.getBusinessId(),
                            order.getUserId(),
                            order.getAmount(),
                            order.getPaymentMethod(),
                            result.getThirdPartyTradeNo()
                        );
                        eventPublisher.publishEvent(event);
                        logger.info("发布支付成功事件: {}", event);
                    }
                    order.setNotifyCount(order.getNotifyCount() + 1);
                    order.setLastNotifyTime(LocalDateTime.now());
                }
                
                logger.info("支付回调处理成功: orderNo={}, status={}", 
                           result.getOrderNo(), result.getStatus());
            } else {
                logger.warn("支付回调处理失败: orderNo={}, message={}", 
                           callback.getOrderNo(), result.getMessage());
            }
            
            return Result.success(result.getMessage(), result.isSuccess());
            
        } catch (Exception e) {
            logger.error("处理支付回调异常: provider={}, orderNo={}", 
                        provider, callback.getOrderNo(), e);
            return Result.error("处理支付回调异常: " + e.getMessage());
        }
    }
    
    @Override
    public Result<PaymentStatus> syncPaymentStatus(String orderNo) {
        PaymentStatus status = queryPaymentStatus(orderNo);
        return Result.success("同步支付状态成功", status);
    }
    
    @Override
    public Map<String, Object> getPaymentStatistics(String timeRange) {
        Map<String, Object> stats = new HashMap<>();
        
        // 模拟统计数据
        stats.put("totalOrders", orderStorage.size());
        stats.put("successCount", orderStorage.values().stream()
            .mapToLong(o -> PaymentStatus.SUCCESS.getCode().equals(o.getStatus()) ? 1 : 0)
            .sum());
        stats.put("failedCount", orderStorage.values().stream()
            .mapToLong(o -> PaymentStatus.FAILED.getCode().equals(o.getStatus()) ? 1 : 0)
            .sum());
        stats.put("timeRange", timeRange);
        
        return stats;
    }
    
    @Override
    public Result<Boolean> checkPaymentAvailable(String orderNo) {
        PaymentOrder order = orderStorage.get(orderNo);
        if (order == null) {
            return Result.error("订单不存在");
        }
        
        PaymentStatus status = PaymentStatus.fromCode(order.getStatus());
        boolean available = status == PaymentStatus.PENDING || status == PaymentStatus.PROCESSING;
        
        return Result.success(available ? "订单可支付" : "订单不可支付", available);
    }
    
    @Override
    public Result<PaymentResponse> retryPayment(String orderNo, String newPaymentMethod) {
        // 重试支付的简化实现
        PaymentOrder order = orderStorage.get(orderNo);
        if (order == null) {
            return Result.error("订单不存在");
        }
        
        // 创建新的支付请求
        PaymentRequest request = PaymentRequest.builder()
            .orderNo(orderNo + "_RETRY_" + System.currentTimeMillis())
            .businessType(order.getBusinessType())
            .businessId(order.getBusinessId())
            .userId(order.getUserId())
            .amount(order.getAmount())
            .subject(order.getSubject())
            .body(order.getBody())
            .paymentMethod(newPaymentMethod)
            .build();
        
        return createPayment(request);
    }
    
    @Override
    public Map<String, Object> getAvailablePaymentMethods(String scene) {
        Map<String, Object> methods = new HashMap<>();
        
        // 模拟返回可用支付方式
        methods.put("wechat", PaymentMethod.WECHAT_NATIVE.getDescription());
        methods.put("alipay", PaymentMethod.ALIPAY_PC.getDescription());
        
        return methods;
    }
    
    @Override
    public Result<PaymentOrder> preCreateOrder(PaymentRequest request) {
        try {
            PaymentOrder order = createLocalOrder(request);
            orderStorage.put(order.getOrderNo(), order);
            
            return Result.success("预创建订单成功", order);
            
        } catch (Exception e) {
            logger.error("预创建订单异常", e);
            return Result.error("预创建订单异常: " + e.getMessage());
        }
    }
    
    @Override
    public int processExpiredOrders() {
        int count = 0;
        LocalDateTime now = LocalDateTime.now();
        
        for (PaymentOrder order : orderStorage.values()) {
            if (order.getExpireTime() != null && 
                order.getExpireTime().isBefore(now) && 
                PaymentStatus.PENDING.getCode().equals(order.getStatus())) {
                
                order.setStatus(PaymentStatus.CLOSED.getCode());
                order.setCloseTime(now);
                count++;
            }
        }
        
        logger.info("处理过期订单: 共{}笔", count);
        return count;
    }
    
    @Override
    public boolean verifyCallbackSignature(String provider, PaymentCallback callback) {
        PaymentProvider paymentProvider = getPaymentProviderById(provider);
        return paymentProvider != null && paymentProvider.verifyCallback(callback);
    }
    
    /**
     * 验证支付请求
     */
    private Result<String> validatePaymentRequest(PaymentRequest request) {
        if (request == null) {
            return Result.error("支付请求不能为空");
        }
        
        if (StrUtil.isBlank(request.getOrderNo())) {
            return Result.error("订单号不能为空");
        }
        
        if (request.getAmount() == null || request.getAmount().compareTo(java.math.BigDecimal.ZERO) <= 0) {
            return Result.error("支付金额必须大于0");
        }
        
        if (StrUtil.isBlank(request.getPaymentMethod())) {
            return Result.error("支付方式不能为空");
        }
        
        return Result.success("验证通过");
    }
    
    /**
     * 创建本地订单
     */
    private PaymentOrder createLocalOrder(PaymentRequest request) {
        PaymentOrder order = new PaymentOrder(
            request.getOrderNo(),
            request.getBusinessType(),
            request.getBusinessId(),
            request.getUserId(),
            request.getAmount(),
            request.getSubject(),
            request.getPaymentMethod()
        );
        
        order.setId(IdUtil.fastSimpleUUID());
        order.setBody(request.getBody());
        order.setPaymentScene(request.getPaymentScene());
        order.setClientIp(request.getClientIp());
        order.setUserAgent(request.getUserAgent());
        order.setExpireTime(request.getExpireTime());
        order.setNotifyUrl(request.getNotifyUrl());
        order.setReturnUrl(request.getReturnUrl());
        order.setExtraData(request.getExtraData());
        
        return order;
    }
    
    /**
     * 获取支付提供商
     */
    private PaymentProvider getPaymentProvider(String paymentMethod) {
        if (paymentProviders == null || paymentProviders.isEmpty()) {
            return null;
        }
        
        try {
            PaymentMethod method = PaymentMethod.fromCode(paymentMethod);
            
            for (PaymentProvider provider : paymentProviders) {
                if (provider.isSupported(method)) {
                    return provider;
                }
            }
        } catch (Exception e) {
            logger.warn("获取支付提供商失败: paymentMethod={}", paymentMethod, e);
        }
        
        return null;
    }
    
    /**
     * 根据ID获取支付提供商
     */
    private PaymentProvider getPaymentProviderById(String providerId) {
        if (paymentProviders == null || paymentProviders.isEmpty()) {
            return null;
        }
        
        for (PaymentProvider provider : paymentProviders) {
            if (provider.getProviderId().equals(providerId)) {
                return provider;
            }
        }
        
        return null;
    }
}
